package com.test.controller;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.sun.xml.internal.ws.util.xml.CDATA;
import com.test.config.TestConfigProperty;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.io.*;
import java.util.*;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/redis")
public class RedisController {
    @Autowired
    @Qualifier("redisTemplate")
    RedisTemplate<String, Object> redisLocal;

    @Autowired
    @Qualifier("redisDevT")
    RedisTemplate<String, Object> redisDev;

    @Autowired
    @Qualifier("redisTestT")
    RedisTemplate<String, Object> redisTest;

    final String us = "market:handicap:US:*";
    final String dlus = "market:delayhandicap:US:*";
    final String hk = "market:handicap:HK:*";
    final String a = "market:handicap:a:*";

    @RequestMapping("test")
    public Object test() {

        return new Date();
    }

    @RequestMapping("local")
    public Object local() {
        String pattern = "market:handicap:*";
        Set<String> keys = redisDev.keys(pattern);

        for (String key : keys) {
            String s = (String) redisDev.opsForValue().get(key);
            assert s != null;
            redisLocal.opsForValue().set(key, s.toString());

        }
        return "success";
    }

    @RequestMapping("hk")
    public Object hk() {
        Set<String> keys = redisDev.keys(hk);
        for (String key : keys) {
            Object o = redisDev.opsForValue().get(key);
            redisLocal.opsForValue().set(key, o.toString());
        }
        return "success";
    }

    @RequestMapping("us")
    public Object us() {
        Set<String> keys = redisDev.keys(us);
        for (String key : keys) {
            String s = (String) redisDev.opsForValue().get(key);
            redisLocal.opsForValue().set(key, s);
        }
        return "success";
    }

    @RequestMapping("local_us")
    public Object localUs() {
        redisLocal.setValueSerializer(new StringRedisSerializer());
        Set<String> keys = redisLocal.keys(us);
        for (String key : keys) {
            String s = (String) redisLocal.opsForValue().get(key);
            int i = s.indexOf("\"");
            if (i == 0) {
                redisLocal.delete(key);
                continue;
            }
            redisLocal.opsForValue().set(key, s.replace("listedDate", "listingDate"));
        }

        return "success";
    }

    @RequestMapping("dev_us")
    public Object devUs() {
        Set<String> keys = redisDev.keys(hk);
        for (String key : keys) {
            String s = (String) redisDev.opsForValue().get(key);
            int i = s.indexOf("\"");
            if (i == 0) {
                redisDev.delete(key);
                continue;
            }
            redisDev.opsForValue().set(key, s.replace("listedDate", "listingDate"));
        }

        return "success";
    }

    @RequestMapping("local_dl_us")
    public Object localDlUs() {
        Set<String> keys = redisLocal.keys(dlus);
        for (String key : keys) {
            String s = (String) redisLocal.opsForValue().get(key);
            int i = s.indexOf("\"");
            if (i == 0) {
                redisLocal.delete(key);
                continue;
            }
            redisLocal.opsForValue().set(key, s.replace("listedDate", "listingDate"));
        }

        return "success";
    }

    @RequestMapping("local_delay")
    public Object localDelay() {

        String key1 = null;
        try {
            String pattern = "market:handicap:US:*";
            String delay = "market:delayhandicap:";
            Set<String> keys = redisDev.keys(pattern);

            for (String key : keys) {
                key1 = key;
                Object o = redisDev.opsForValue().get(key);
                assert o != null;
                String[] split = key.split(":");
                redisLocal.opsForValue().set(delay.concat("US:").concat(split[split.length - 1]), o.toString());

            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "success";
    }

    @RequestMapping("test_for")
    public Object forTest() {
        Set<String> keys = redisTest.keys("market:handicap:HK:*");
        for (String key : keys) {
            Object o = redisTest.opsForValue().get(key);
            redisLocal.opsForValue().set(key, o.toString());
        }
        return "success";
    }


    @RequestMapping("test_copy")
    public Object testCopy() {
        String hashKey = "stock:table:us";
        Set<Object> keys = redisTest.opsForHash().keys(hashKey);
        Map<String, String> copy = new HashMap<>();
        for (Object key : keys) {
            Object o = redisTest.opsForHash().get(hashKey, key);
            copy.put(key.toString(), o.toString());
        }
        try (FileOutputStream fileOutputStream = new FileOutputStream("C:\\Users\\Administrator\\Desktop\\ustable1");
             ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream)) {
            objectOutputStream.writeObject(copy);
        } catch (IOException e) {
            e.printStackTrace();
        }
        List<String> filterEtf = filterEtf(copy);
        Long delete = redisTest.opsForHash().delete(hashKey, filterEtf.toArray(new Object[filterEtf.size()]));
        return "success";
    }

    private List<String> filter(Map<String, String> data) {
        List<String> remove = new ArrayList<>();
        for (Map.Entry<String, String> stringStringEntry : data.entrySet()) {
            JSONArray objects = JSONObject.parseArray(stringStringEntry.getValue());
            JSONObject jsonObject = (JSONObject) objects.get(1);
            String type = jsonObject.getString("type").trim();
            if (!("A".equals(type) || "C".equals(type) || "F".equals(type) || "O".equals(type) || "P".equals(type) || "Q".equals(type) || "U".equals(type))) {
                remove.add(stringStringEntry.getKey());
            }
        }
        return remove;
    }

    private List<String> filterEtf(Map<String, String> data) {
        Set<String> indexSet = new HashSet<>();
        indexSet.add("DIA");
        indexSet.add("QQQ");
        indexSet.add("SPY");
        List<String> remove = new ArrayList<>();
        List<String> etflist = new ArrayList<>();
        for (Map.Entry<String, String> stringStringEntry : data.entrySet()) {
            JSONArray objects = JSONObject.parseArray(stringStringEntry.getValue());
            JSONObject jsonObject = (JSONObject) objects.get(1);
            String etf = jsonObject.getString("etf").trim();
            if ("Y".equals(etf) && !indexSet.contains(stringStringEntry.getKey())) {
                remove.add(stringStringEntry.getKey());
            }
            if ("Y".equals(etf)) {
                etflist.add(stringStringEntry.getKey());
            }
        }
        return remove;
    }

    @RequestMapping("test_ustable")
    public Object test_ustable() {

        try (
                FileInputStream fileInputStream = new FileInputStream("C:\\Users\\Administrator\\Desktop\\ustable");
                ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream)) {
            Map<String, String> stringStringMap = (Map<String, String>) objectInputStream.readObject();
            return "success";
        } catch (Exception e) {
            e.printStackTrace();
            return "success";
        }
    }

    @RequestMapping("/diffTest")
    public Object diffTest() {

        String key = "stock:table:A:SZ";
        Set<Object> members = redisLocal.opsForSet().members(key);

        redisDev.opsForSet().add(key, members.toArray());
        return "success";
    }

    @RequestMapping("/map")
    public Object mapAndFlagMap() {
        String[] strings = {"Hello", "World"};
/*        List<Stream> streamList = Arrays.asList(strings).stream().
                map(str -> str.split("")).
                map(str -> Arrays.stream(str)).
                collect(Collectors.toList());*/
        List<String> collect = Arrays.stream(strings).map(str -> str.split("")).flatMap(Arrays::stream).distinct().collect(Collectors.toList());
        System.out.println(collect);
        return "success";
    }

    @Resource
    private TestConfigProperty testConfigProperty;

    @RequestMapping("testtest")
    public Object testtest() {
        return "success";
    }

    private static class Node {
        List<Node> children;
        String label;
        String buf;
        String prefix;
    }

    @RequestMapping("updateNameDev")
    public Object updateNameDev() {
        Set<String> keys = redisDev.keys("market:handicap:SZ:*");
        List<String> noName = new ArrayList<>();
        for (String key : keys) {
            Object o = redisDev.opsForValue().get(key);
            JSONArray objects = JSONObject.parseArray(o.toString());
            JSONObject jsonObject = objects.getJSONObject(1);
            String name = jsonObject.getString("name");
            if (name == null) {
                noName.add(key);
            }
        }
        for (String s : noName) {
            Object data = redisTest.opsForValue().get(s);
            if (data == null) {
                continue;
            }
            redisDev.opsForValue().set(s, data.toString());
        }
        return "success";
    }

    @RequestMapping("testToLocal")
    public Object testToLocal() {
        String key = "stock:table:us";
        Set<Object> keys2 = redisTest.opsForHash().keys(key);

        for (Object o : keys2) {
            Object o1 = redisTest.opsForHash().get(key, o.toString());
            redisLocal.opsForHash().put(key, o.toString(), o1);
        }
        return "success";
    }
}
